#pragma once
#include "pch.h"
#include "PropertyValueOwner.h"
//#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
//#include <Windows.h>
//#include <roapi.h>
#include <windows.foundation.h>  
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
//namespace ABI {
	namespace Yinyue200 {
		namespace CppWrapper {
			/*[Windows::Foundation::m ::WebHostHidden]*/
			public ref class PropertyValueOwner sealed
			{
				Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> m_propertyValueFactory;
			public:
				PropertyValueOwner();
				int64 GetFactoryPointer();
				int64 CreateUInt32(UINT value);
				int64 CreateInt32(int value);
				int64 CreateSingle(float value);
				int64 CreateBoolean(bool value);
				int64 CreateSingleArray(const Platform::Array<float>^ value);
				//ComPtr<IPropertyValue> PropertyValueOwner::CreatePropertyValue(IInspectable* value)
				//ABI::Windows::Foundation::IPropertyValue& CreateInt32(int value);
				//ABI::Windows::Foundation::IPropertyValue& CreateSingle(float value);
				//ABI::Windows::Foundation::IPropertyValue& CreateInspectable(Platform::Object value);
				//ABI::Windows::Foundation::IPropertyValue& CreateBoolean(bool value);

				//virtual ~PropertyValueOwner()
				//{
				//	m_propertyValueFactory.Reset();
				//}
			private:
				template<typename TBoxed, typename TPublic, typename Enable = void>
				struct PropertyTypeConverter
				{
					static_assert(std::is_same<TBoxed, TPublic>::value, "Default PropertyTypeConverter should only be used when TBoxed = TPublic");

					static ComPtr<IPropertyValue> Box(IPropertyValueStatics* factory, TPublic const& value)
					{
						return CreateProperty(factory, value);
					}

					static void Unbox(IPropertyValue* propertyValue, TPublic* result)
					{
						GetValueOfProperty(propertyValue, result);
					}
				};

				// Interface types are stored as a PropertyType_InspectableArray containing a single IInspectable.
				// This is because IPropertyValue provides CreateInspectableArray, but not CreateInspectable.
				static ComPtr<IPropertyValue> CreateProperty(IPropertyValueStatics* factory, IInspectable* value)
				{
					ComPtr<IPropertyValue> propertyValue;
					factory->CreateInspectableArray(1, &value, &propertyValue);
					return propertyValue;
				}

				template<typename T>
				static void GetValueOfProperty(IPropertyValue* propertyValue, T** result)
				{
					static_assert(std::is_base_of<IInspectable, T>::value, "Interface types must be IInspectable");

					ComArray<ComPtr<IInspectable>> value;
					ThrowIfFailed(propertyValue->GetInspectableArray(value.GetAddressOfSize(), value.GetAddressOfData()));

					if (value.GetSize() != 1)
						ThrowHR(E_NOTIMPL);

					if (value[0])
						ThrowIfFailed(value[0].CopyTo(result));
					else
						*result = nullptr;
				}
			};
		}
	}
//}


